package io.renren.common.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import io.renren.common.utils.Result;
import io.renren.modules.sp.dto.SpUserDTO;
import io.renren.modules.sp.dto.SpUserImport;
import io.renren.modules.sp.entity.SpUserEntity;
import io.renren.modules.sp.service.SpUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 选手荣誉证书导入
 */
@Slf4j
public class SpUserImportListener extends AnalysisEventListener<SpUserImport> {

    private Result result;

    private SpUserService spUserService;
    /**
     * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 3000;
    private static int PROCESS, TOTAL = 0;
    List<SpUserImport> list;

    public SpUserImportListener(SpUserService userService, Result result, List<SpUserImport> list) {
        this.spUserService = userService;
        this.result = result;
        this.list = list;
    }

    @Override
    public void invoke(SpUserImport data, AnalysisContext context) {
        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        PROCESS++;
        list.add(data);
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            list.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        TOTAL = 0;
        PROCESS = 0;
        log.info("所有数据解析完成！");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据，开始存储数据库！", list.size());
        if (!CollectionUtils.isEmpty(list)) {
            List<SpUserEntity> saveList = new ArrayList();
            // 校验list中的Certificate字段是否重复
            //List<String> certificateList = new ArrayList<>();
            for(SpUserImport user : list){
                if(StringUtils.isEmpty(user.getPhone())){
                    result.setCode(0);
                    result.setData("error");
                    result.setMsg("手机号不能为空");
                    return;
                }
                //身份证号不能重复
                if(StringUtils.isEmpty(user.getIdCard())){
                    result.setCode(0);
                    result.setData("error");
                    result.setMsg("身份证号不能为空");
                    return;
                }
                //校验证件类型是否合规   居民身份证\临时身份证\港澳居民来往内地通行证\台湾居民来往大陆通行证
                if(StringUtils.isNotEmpty(user.getIdType())) {
                    String[] validIdTypes = {"居民身份证", "临时身份证", "港澳居民来往内地通行证", "台湾居民来往大陆通行证"};
                    boolean isValid = false;
                    for (String validType : validIdTypes) {
                        if (validType.equals(user.getIdType())) {
                            isValid = true;
                            break;
                        }
                    }
                    if (!isValid) {
                        result.setCode(0);
                        result.setData("error");
                        result.setMsg("证件类型不合法，必须是:居民身份证、临时身份证、港澳居民来往内地通行证或台湾居民来往大陆通行证");
                        return;
                    }
                }

            }

            SpUserEntity userDto = new SpUserEntity();
            for(SpUserImport user : list){
                userDto = new SpUserEntity();
                // 校验身份证是否已经注册过
                Map<String, Object> param2 = new HashMap<String, Object>();
                param2.put("idCard", user.getIdCard());
                List<SpUserDTO> userList2 = spUserService.list(param2);
                if (userList2.size() > 0) {
                    user.setCheckMsg("身份证已经注册过");
                }

                // 校验手机号是否已经注册过
                Map<String, Object> param3 = new HashMap<String, Object>();
                param3.put("phone", user.getPhone());
                List<SpUserDTO> userList3 = spUserService.list(param3);
                if (userList3.size() > 0) {
                    user.setCheckMsg("手机号已经注册过");
                }

                if(StringUtils.isNotEmpty(user.getCheckMsg())){
                    result.setCode(0);
                    result.setData("error");
                    result.setMsg(user.getCheckMsg());
                }
                //账号
                userDto.setAccount(user.getPhone());
                //电话
                userDto.setPhone(user.getPhone());
                //证件类型
                // 根据证件类型设置对应的type值
                switch(user.getIdType()){
                    case "居民身份证":
                        userDto.setIdType("1");
                        break;
                    case "临时身份证":
                        userDto.setIdType("2");
                        break;
                    case "港澳居民来往内地通行证":
                        userDto.setIdType("3");
                        break;
                    case "台湾居民来往大陆通行证":
                        userDto.setIdType("4");
                        break;
                    default:
                        userDto.setIdType("1"); // 默认居民身份证
                }
                //身份证
                userDto.setIdCard(user.getIdCard());
                //邮箱
                userDto.setEmail(user.getEmail());
                //角色：代表队负责人、领队、指导老师、选手
                String roleType = user.getRoleType();
                if (StringUtils.isBlank(roleType)) {
                    user.setCheckMsg("角色不能为空");
                } else {
                    String[] rs = roleType.split(" ");
                    Set<String> roleSet = new HashSet<>(Arrays.asList(rs)); // 去重

                    // 1. 检查角色是否合法
                    String[] standRole = {"代表队负责人", "领队", "指导老师", "选手"};
                    for (String r : roleSet) {
                        if (!ArrayUtils.contains(standRole, r)) {
                            user.setCheckMsg("角色'" + r + "'输入有误，必须是: 代表队负责人、领队、指导老师或选手");
                        }
                    }

                    // 2. 选手身份独立：选了"选手"就不能选其他角色
                    if (roleSet.contains("选手") && roleSet.size() > 1) {
                        user.setCheckMsg("选手身份不能与其他角色同时选择");
                    }

                    // 3. 代表队负责人和领队互斥
                    if (roleSet.contains("代表队负责人") && roleSet.contains("领队")) {
                        user.setCheckMsg("代表队负责人和领队不能同时选择");
                    }
                }

                String roleStr = "";
                if(StringUtils.isNotEmpty(roleType)){
                    if(roleType.contains("代表队负责人")){
                        roleStr += "0,";
                    }
                    if(roleType.contains("领队")){
                        roleStr += "1,";
                    }
                    if(roleType.contains("指导老师")){
                        roleStr += "2,";
                    }
                    if(roleType.contains("选手")){
                        roleStr += "3,";
                    }
                }
                if(StringUtils.isNotEmpty(roleStr)){
                    userDto.setRoleId(roleStr.substring(0,roleStr.length()-1));
                }
                //真实姓名
                userDto.setRealName(user.getRealName());

                //性别
                String sex = user.getSex();
                if(sex.equals("男")){
                    userDto.setSex(1);
                }else{
                    userDto.setSex(0);
                }
                //参赛单位
                userDto.setCompany(user.getCompany());
                saveList.add(userDto);
            }
            for(SpUserImport user : list){
                if(StringUtils.isNotEmpty(user.getCheckMsg())){
                    return;
                }
            }
            try{
                spUserService.insertBatch(saveList);
                TOTAL += saveList.size();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        log.info("存储数据库成功！");
    }
}
